About 2115 letters

About 11 minutes

#Python's reentrant lock

A regular mutex lock can only be acquired once. If the same thread tries to acquire it again before releasing it, it will block and potentially deadlock. Sometimes, however, a thread needs to perform multiple operations on a shared variable, and if the lock is acquired multiple times, it may lead to permanent blocking.

For example:

from threading import Lock # Counter class Counter: def __init__(self): self.__value = 0 self.__lock = Lock() # Increment the counter def increase(self): with self.__lock: # Re-acquiring the lock self.__value += 1 # Get the value and auto-increment def touch(self): value = 0 with self.__lock: # Acquire lock value = self.__value self.increase() return value # Global variable counter = Counter() # Invocation counter.touch() print('Done')

In large projects, it's often hard to ensure whether a lock has already been acquired within a function or interface. In such cases, you can use a reentrant lock (ReentrantLock).

A reentrant lock allows the same thread to acquire the lock multiple times. It must also release it the same number of times for the lock to be fully released.

In Python, use the RLock class from the threading module to create a reentrant lock. It provides acquire and release methods and supports the with statement.

The previous code can be modified as follows:

from threading import RLock # Counter class Counter: def __init__(self): self.__value = 0 self.__lock = RLock() # Increment the counter def increase(self): with self.__lock: # Re-acquire lock self.__value += 1 # Get the value and auto-increment def touch(self): value = 0 with self.__lock: # Acquire lock value = self.__value self.increase() return value # Global variable counter = Counter() # Invocation counter.touch() print('Done')

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

Created in 5/15/2025

Updated in 5/21/2025